package cn.swh.guguanjia.aspect;

import cn.swh.guguanjia.entity.SysLog;
import cn.swh.guguanjia.entity.SysUser;
import cn.swh.guguanjia.service.SysLogService;
import cn.swh.guguanjia.util.IPUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 日志处理：
 * 1.声明日志处理切面组件，被spring管理
 * 2.设置切入点表达式
 * 3.设置需要进行日志切入的通知
 *
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    SysLogService logService;

    @Autowired
    HttpServletRequest request;


    //指定within表达式：设置到类级别下所有方法记录日志
    @Pointcut(value = "within(cn.swh.guguanjia.service.impl.*AppVersionServicelmpl)")
    public void pointcut(){}

    /**
     * 正常日志通知
     * JoinPoint:连接点  拦截到进行切面处理的方法对象
     * 实际MethodInvocationProceedingJoinPoint
     * java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut
     * 必须设置返回值
     *
     */
    @AfterReturning(pointcut = "pointcut()",returning = "obj")
    public Object afterReturning(JoinPoint joinPoint, Object obj){
        String className = joinPoint.getTarget().getClass().getSimpleName();
        if(!className.equals("SysLogServicelmpl")) {
            insert(null, joinPoint);
        }
        return obj;
    }

    /**
     * 异常日志通知
     * 必须先传入joinPoint
     */
    @AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint,Exception e){
        insert(e,joinPoint);
    }


    /**
     * 插入日志处理方法：
     */
    public void insert(Exception e,JoinPoint joinPoint){
        SysLog sysLog = new SysLog();

        sysLog.setType(e==null?"1":"2");

        if(request!=null){
            SysUser loginUser = (SysUser) request.getSession().getAttribute("login");
            if(loginUser!=null){
                sysLog.setCreateBy(loginUser.getName());
            }
            sysLog.setCreateDate(new Date());
            sysLog.setRemoteAddr(IPUtils.getClientAddress(request));
            //客户端信息
            sysLog.setUserAgent(request.getHeader("User-Agent"));
            sysLog.setRequestUri(request.getRequestURI());
            sysLog.setMethod(request.getMethod());
        }
        Object[] args = joinPoint.getArgs();

        if(args!=null&&args.length>0){
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < args.length; i++) {
                //[参数1，类型:SysUser，值:{"password":"aaaa","mobile":"139999"}]
                sb.append("[参数")
                        .append(i+1)
                        .append(",类型:")
                        .append(args[i].getClass().getSimpleName())
                        .append(",值:")
                        .append(args[i])
                        .append("],");
            }
            sb.deleteCharAt(sb.length()-1);//删除多余的最后逗号
            sysLog.setParams(sb.toString());
        }
        sysLog.setException(e==null?"":e.toString());
        sysLog.setDescription("日志记录");

        logService.insertSelective(sysLog);
    }
}
